package values

import (
	"reflect"
	"reflect_fast/model"
	"reflect_fast/utils"
	value2 "reflect_fast/value"
)

type ReflectValues struct {
	model   *model.Model
	vals    reflect.Value
	valType reflect.Type
	creator value2.Creator
}

func (r *ReflectValues) generateModel(val any) error {
	m, err := model.NewModel(val)
	if err != nil {
		return err
	}
	err = m.ParseModel()
	if err != nil {
		return err
	}
	r.model = m
	return nil
}

func (r *ReflectValues) SetValues(newVals ...interface{}) error {
	for _, newVal := range newVals {
		valInstance := reflect.New(r.valType).Interface()

		if r.model == nil {
			err := r.generateModel(valInstance)
			if err != nil {
				return err
			}
		}

		value, err := r.creator(valInstance, r.model)
		if err != nil {
			return err
		}
		err = value.SetValue(newVal)
		if err != nil {
			return err
		}
		r.vals.Set(reflect.Append(r.vals, reflect.ValueOf(valInstance)))
	}
	return nil
}

// NewReflectValues vals需要是指向切片的指针,切片元素需要是指向结构体的指针,示例: userList := make([]*User, 0),需要传入&userList
func NewReflectValues(vals any, creator value2.Creator) (*ReflectValues, error) {
	valTyp, err := utils.ValidateValuesTyp(vals)
	if err != nil {
		return nil, err
	}

	return &ReflectValues{
		vals:    reflect.ValueOf(vals).Elem(),
		valType: valTyp,
		creator: creator,
	}, nil
}
